home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
asmutil
/
a86v400.zip
/
A08.DOC
< prev
next >
Wrap
Text File
|
1994-12-21
|
26KB
|
661 lines
CHAPTER 8 NUMBERS AND EXPRESSIONS
Numbers and Bases
A86 supports a variety of formats for numbers. In non-computer
life, we write numbers in a decimal format. There are ten
digits, 0 through 9, that we use to describe numbers; and each
digit position is ten times as significant as the position to its
right. The number ten is called the "base" of the decimal
format. Computer programmers often find it convenient to use
other bases to specify numbers used in their programs. The most
commonly-used bases are two (binary format), sixteen (hexadecimal
format), and eight (octal format).
The hexadecimal format requires sixteen digits. The extra six
digits beyond 0 through 9 are denoted by the first six letters of
the alphabet: A for ten, B for eleven, C for twelve, D for
thirteen, E for fourteen, and F for fifteen.
In A86, a number must always begin with a digit from 0 through 9,
even if the base is hexadecimal. This is so that A86 can
distinguish between a number and a symbol that happens to have
digits in its name. If a hexadecimal number would begin with a
letter, you precede the letter with a zero. For example, hex A0,
which is the same as decimal 160, would be written 0A0.
Because it is necessary for you to append leading zeroes to many
hex numbers, and because you never have to do so for decimal
numbers, I decided to make hexadecimal the default base for
numbers with leading zeroes. Decimal is still the default base
for numbers beginning with 1 through 9.
Large numbers can be given as the operands to DD, DQ, or DT
directives. For readability, you may freely intersperse
underscore characters anywhere with your numbers.
The default base can be overridden, with a letter or letters at
the end of the number: B or xB for binary, O or Q for octal, H
for hexadecimal, and D or xD for decimal. Examples:
077Q octal, value is 8*7 + 7 = 63 in decimal notation
123O octal if the "O" is a letter: 64 + 2*8 + 3 = 83 decimal
1230 decimal 1230: shows why you should use "Q" for octal!!
01234567H large constant
0001_0000_0000_0000_0003R real number specified in hexadecimal
100D superfluous D indicates decimal base
0100D hex number 100D, which is 4096 + 13 = 5009 in decimal
0100xD decimal 100, since xD overrides the default hex format
0110B hex 110B, which is 4096 + 256 + 11 = 4363 in decimal
0110xB binary 4+2 = 6 in decimal notation
110B also binary 4+2 = 6, since "B" is not a decimal digit
8-2
The last five examples above illustrate why an "x" is sometimes
necessary before the base-override letter "B" or "D". If that
letter can be interpreted as a hex digit, it is; the "x" forces
an override interpretation for the "B" or "D". By the way, the
usage of lower case for x and upper case for the following
override letter is simply a recommendation; A86 treats upper-and
lower-case letters equivalently.
A86 also accepts a "base" of K. The number preceding the K is
interpreted as a decimal number which is multplied by 1024.
Thus, 2K is 2048, 16K is 16384, etc.
The RADIX Directive
The above-mentioned set of defaults (hex if leading zero, decimal
otherwise) can be overridden with the RADIX (or, for
compatibility, .RADIX) directive. The RADIX directive consists
of the word RADIX followed by a number from 2 to 16. The default
base for the number is ALWAYS decimal, regardless of any (or no)
previous RADIX commands. The number gives the default base for
ALL subsequent numbers, up to (but not including) the next RADIX
command. If there is no number following RADIX, then A86 returns
to its initial mixed default of hex for leading zeroes, decimal
for other leading digits.
As an alternative to the RADIX directive, I provide the D switch,
which causes A86 to start with decimal defaults. You can put +D
into the A86 command invocation, or into the A86 environment
variable. The first RADIX command in the program will override
the D switch setting.
Following are examples of radix usage. The numbers in the
comments are all in decimal notation.
DB 10,010 ; produces 10,16 if RADIX was not seen yet
; and +D switch was not specified
RADIX 10
DB 10,010 ; produces 10,10
RADIX 16
DB 10,010 ; produces 16,16
RADIX 3 ; for Martian programmers in Heinlein novels
DB 10,100 ; produces 3,9
RADIX
DB 10,010 ; produces 10,16
8-3
Floating Point Initializations
A86 allows floating point numbers as the operands to DD, DQ, and
DT directives. The numbers are encoded according to the IEEE
standard, followed by the 8087 and 287 coprocessors. The format
for floating point constants is as follows: First, there is a
decimal number containing a decimal point. There must be a
decimal point, or else the number is interpreted as an integer.
There must also be at least one decimal digit, either to the left
or right of the decimal point, or else the decimal point is
interpreted as an addition (structure element) operator.
Optionally, there may follow immediately after the decimal number
the letter E followed by a decimal number. The E stands for
"exponent", and means "times 10 raised to the power of". You may
provide a + or - between the E and its number. Examples:
0.1 constant one-tenth
.1 the same
300. floating point three hundred
30.E1 30 * 10**1; i.e., three hundred
30.E+1 the same
30.E-1 30 * 10**-1; i.e., three
30E1 not floating point: hex integer 030E1
1.234E20 scientific notation: 1.234 times 10 to the 20th
1.234E-20 a tiny number: 1.234 divided by 10 to the 20th
Overview of Expressions
Most of the operands that you code into your instructions and
data initializations will be simple register names, variable
names, or constants. However, you will regularly wish to code
operands that are the results of arithmetic calculations,
performed either by the machine when the program is running (for
indexing), or by the assembler (to determine the value to
assemble into the program). A86 has a full set of operators that
you can use to create expressions to cover these cases. They are
given in the "Descriptions of Operators and Specifiers" section
later in this chapter.
Types of Expression Operands
Numbers and Label Addresses
A number or constant (16-bit number) can be used in most
expressions. A label (defined with a colon) is also treated as
a constant and so can be used in expressions.
Variables
A variable stands for a byte- or word-memory location. You may
add or subtract constants from variables; when you do so, the
constant is added to the address of the variable. You typically
do this when the variable is the name of a memory array.
8-4
Index Expressions
An index expression consists of a combination of a base register
[BX] or [BP], and/or an index register [SI] or [DI], with an
optional constant added or subtracted. You will usually want to
precede the bracketed expression with B, W, or D; to specify the
kind of memory unit (byte, word, or doubleword) you are referring
to. The expression stands for the memory unit whose address is
the run-time value(s) of the base and/or index registers added to
the constant. See the Effective Address section and the
beginning of this chapter for more details on indexed memory.
Descriptions of Operators and Specifiers
HIGH/LOW
Syntax: HIGH operand
LOW operand
These operators are called the "byte isolation" operators. The
operand must evaluate to a 16-bit number. HIGH returns the
high order byte of the number; LOW the low order byte.
For example,
MOV AL,HIGH(01234) ; AL = 012
TENHEX EQU LOW(0FF10) ; TENHEX = 010
These operators can be applied to each other. The following
ident